package ru.usu.gv.utils;

import com.sun.org.apache.xpath.internal.NodeSet;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import ru.usu.gv.core.ResourceLoader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import java.io.InputStream;

/**
 @author: Sergey Pupyrev 
 May 9, 2006
 */

public class XmlUtil
{
	public static Document loadXmlFile(String path) throws Exception
	{
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder xmlBuilder = dbf.newDocumentBuilder();

		//XmlUtil.class.getClassLoader();
		InputStream inputStream = ResourceLoader.getResourceAsStream(path);

		try
		{
			return xmlBuilder.parse(inputStream);
		}
		finally
		{
			if (inputStream != null)
				inputStream.close();
		}
	}

	public static NodeList getChildsByTagName(Node node, String tagName)
	{
		NodeList nodes = node.getChildNodes();
		int count = nodes.getLength();
		NodeSet result = new NodeSet();
		for (int i = 0; i < count; i++)
		{
			Node child = nodes.item(i);
			if (tagName.equals(child.getNodeName()))
				result.addNode(child);
		}
		return result;
	}

	public static boolean existsAttribute(Node node, String attributeName) throws Exception
	{
		Node attribute = node.getAttributes().getNamedItem(attributeName);
		return (attribute != null);
	}

	public static String readStringAttribute(Node node, String attributeName) throws Exception
	{
		Node attribute = node.getAttributes().getNamedItem(attributeName);
		if (attribute == null)
			throw new Exception("Can't find attribute: '" + attributeName + "'");

		return attribute.getNodeValue();
	}

	public static double readDoubleAttribute(Node node, String attributeName) throws Exception
	{
		String value = readStringAttribute(node, attributeName);
		return Double.parseDouble(value);
	}

	public static boolean readBooleanAttribute(Node node, String attributeName) throws Exception
	{
		String value = readStringAttribute(node, attributeName);
		return Boolean.parseBoolean(value);
	}

	public static boolean readBooleanAttribute(Node node, String attributeName, boolean defaultValue) throws Exception
	{
		if (!existsAttribute(node, attributeName))
			return defaultValue;

		String value = readStringAttribute(node, attributeName);
		return Boolean.parseBoolean(value);
	}

	public static int readIntAttribute(Node node, String attributeName) throws Exception
	{
		String value = readStringAttribute(node, attributeName);
		return Integer.parseInt(value);
	}

	public static String readXmlValue(Document document, String path)
	{
		try
		{
			String names[] = path.split("\\.");
			NodeList rootElemets = XmlUtil.getChildsByTagName(document.getElementsByTagName(names[0]).item(0), "attribute");
			for (int i = 0; i < rootElemets.getLength(); i++)
			{
				Node node = rootElemets.item(i);
				String name = XmlUtil.readStringAttribute(node, "name");
				if (name.equals(names[1]))
				{
					return XmlUtil.readStringAttribute(node, "value");
				}
			}

			throw new Exception("Can't find property '" + path + "'");
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}

}
